{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# [实现多线程编程的三种方式](https://www.cnblogs.com/zeroingToOne/p/9064123.html)\n",
    "\n",
    "1. 继承Thread类 （Thread类实现了Runnable接口：public class Thread implements Runnable）\n",
    "2. 实现Runnable接口\n",
    "3. 使用Callable和Future"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实例代码：\n",
    "1. 继承Thread类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyThread extends Thread{\n",
    "    @Override\n",
    "    public void run(){\n",
    "        //run方法\n",
    "    }\n",
    "}\n",
    "\n",
    "public class MyThreadDemo {\n",
    "    public static void main(String[] args) {\n",
    "        MyThread thread = new MyThread();\n",
    "        thread.start();\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 实现Runnable接口\n",
    "\n",
    "(1) 方法一"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "public class MyThreadDemo {\n",
    "    public static void main(String[] args) {\n",
    "        Thread thread = new Thread(new Runnable(){\n",
    "            @Override\n",
    "            public void run(){\n",
    "                //run方法\n",
    "            }\n",
    "        });\n",
    "        thread.start();\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(2) 方法二"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Runner implements Runnable{\n",
    "    @Override\n",
    "    public void run(){\n",
    "        //run方法\n",
    "    }\n",
    "}\n",
    "\n",
    "public class MyThreadDemo {\n",
    "    public static void main(String[] args) {\n",
    "        Runner one = new Runner();\n",
    "        Thread thread = new Thread(one); //都是接收了一个实现了Runnable的对象\n",
    "        thread.start();\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. 使用Callable和Future\n",
    "\n",
    "和Runnable接口不一样，Callable接口提供了一个call()方法作为线程执行体，call()方法比run()方法功能要强大。\n",
    "\n",
    "(1). call()方法可以有返回值\n",
    "\n",
    "(2). call()方法可以声明抛出异常\n",
    "\n",
    "创建并启动有返回值的线程的步骤如下：\n",
    "\n",
    "1】创建Callable接口的实现类，并实现call()方法，然后创建该实现类的实例（从java8开始可以直接使用Lambda表达式创建Callable对象）。\n",
    "\n",
    "2】使用FutureTask类来包装Callable对象，该FutureTask对象封装了Callable对象的call()方法的返回值\n",
    "\n",
    "3】使用FutureTask对象作为Thread对象的target创建并启动线程（因为FutureTask实现了Runnable接口）\n",
    "\n",
    "4】调用FutureTask对象的get()方法来获得子线程执行结束后的返回值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import java.util.concurrent.Callable;\n",
    "import java.util.concurrent.ExecutionException;\n",
    "import java.util.concurrent.FutureTask;\n",
    "\n",
    "public class CreateThread {\n",
    "\n",
    "    public static void main(String[] args) throws InterruptedException, ExecutionException {\n",
    "\n",
    "        // 第三种方式\n",
    "        FutureTask<String> ft = new FutureTask<String>(new Callable<String>() {\n",
    "\n",
    "            @Override\n",
    "            public String call() throws Exception {\n",
    "                System.out.println(\"new Thread 3\");// 输出:new Thread 3\n",
    "                return \"aaaa\";\n",
    "            }\n",
    "        });\n",
    "\n",
    "        Thread t3 = new Thread(ft);\n",
    "        t3.start();\n",
    "        String result = ft.get();\n",
    "        System.out.println(result);// 输出:aaaa\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 三种创建线程方式对比\n",
    "\n",
    "实现Runnable和实现Callable接口的方式基本相同，不过是后者执行call()方法有返回值，前者线程执行体run()方法无返回值，因此可以把这两种方式归为一种，这两种方式与继承Thread类的方法之间的差别如下：\n",
    "1. 线程只是实现Runnable或实现Callable接口，还可以继承其他类。\n",
    "2. 这种方式下，多个线程可以共享一个target对象，非常适合多线程处理同一份资源的情形。\n",
    "3. 如果需要访问当前线程，必须调用Thread.currentThread()方法。\n",
    "4. 继承Thread类的线程类不能再继承其他父类（Java单继承决定）。\n",
    "\n",
    "注：一般推荐采用实现接口的方式来创建多线程"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "11.0.8+10-post-Ubuntu-0ubuntu120.04"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
